#include "stdafx.h"
#include "ASParaseXml.h"


#include <QThread>
#include <QDomDocument>
#include <QDebug>
#include <QFile>
#include <QXmlStreamReader>

inline  static void String2Pt(const QString& str,QPoint& pt)
{
	if(str.isEmpty() || str.size() <= 1)  return;
	QStringList  lst = str.split(",", QString::SkipEmptyParts);
	if(lst.size() < 2) return ;
	pt.setX(lst[0].toLong());
	pt.setY(lst[1].toLong());
}

inline  static void String2ListPt(const QString& str,VTPoint& vtPt)
{
	if(str.isEmpty() || str.size() <= 1)  return;
	QStringList  lst = str.split(":", QString::SkipEmptyParts);
	if(lst.size() < 2) return ;
	for (int i = 0; i < lst.size(); i++)
	{
		QPoint  pt;
		QString seq = lst[i];
		String2Pt(seq,pt);
		vtPt.append(pt);
	}
}

inline  static void String2Length(const QString& str,VTLong& vtLen)
{
	if(str.isEmpty() || str.size() <= 1)  return;
	QStringList  lst = str.split(",", QString::SkipEmptyParts);
	if(lst.size() < 2) return ;
	for (int i=0;i<lst.size();++i)
	{
		vtLen.append(lst[i].toLong());
	}

}

ASParaseXml::ASParaseXml(QString strFileName,QObject *parent)
	: QObject(parent),m_strFileName(strFileName)
{
	m_nFinishedThread = 0;
}

ASParaseXml::~ASParaseXml()
{

}

bool ASParaseXml::startParaseXml()
{
	QFile xmlFile(m_strFileName);

	 if(!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))  return false;

	
	
	QDomDocument m_domDoc;
	if(!m_domDoc.setContent(&xmlFile)){
		xmlFile.close();
		return false;
	}

	xmlFile.close();

	QDomNode xmlfirstNode = m_domDoc.firstChild();

	qDebug()<<qPrintable(xmlfirstNode.nodeName()) 
		<<qPrintable(xmlfirstNode.nodeValue());

	if(xmlfirstNode.nodeName().toLower() != "xml")  return false;

	QDomElement dataElem = m_domDoc.documentElement();

	if(dataElem.nodeName().toLower() != "root") return false;

	qDebug()<<qPrintable(dataElem.nodeName()) 
		<<qPrintable(dataElem.nodeValue());
	
	QDomNodeList  nodeList = dataElem.childNodes();
	qDebug()<<"node count" <<nodeList.count();
	for (int i=0;i<nodeList.count();++i)
	{
		QDomNode  node = nodeList.at(i);
		qDebug()<<node.nodeName();

		if(node.nodeName().toLower() == "result")
		{
			QDomNodeList subNodeList = node.childNodes();

			
			paraseResultInfo(&m_stuResultInfo,subNodeList);
		}

		else if(node.nodeName().toLower() == "onebubble")
		{
			QDomNodeList subNodeList = node.childNodes();
			
			paraseBubbleInfo(&m_stuResultInfo,subNodeList);
		}

		else if(node.nodeName().toLower() == "line")
		{
			QDomNodeList subNodeList = node.childNodes();

			paraseLineInfo(&m_stuResultInfo,subNodeList);
		}
		
	}

	return true;
}

bool ASParaseXml::paraseResultInfo( ASResultInfo* pstuResultInfo,const QDomNodeList& subNodeList )
{
	for (int nSub=0;nSub<subNodeList.count();++nSub)
	{
		QDomNode  subNode = subNodeList.at(nSub);
		QDomElement eSubEle = subNode.toElement();

		qDebug()<<qPrintable(eSubEle.tagName()) 
			<<qPrintable(eSubEle.text());
		if(eSubEle.tagName().toLower() == "allbubblenum")
		{
			pstuResultInfo->lTotalBubbleNum = eSubEle.text().toLong();
		}

		else if(eSubEle.tagName().toLower() == "allbubblearea")
		{
			pstuResultInfo->lTotalBubbleArea = eSubEle.text().toLong();
		}

		else if(eSubEle.tagName().toLower() == "linenum")
		{
			pstuResultInfo->lTotalLineNum = eSubEle.text().toLong();
		}

		else if(eSubEle.tagName().toLower() == "imagewidth")
		{
			pstuResultInfo->lImageWidth = eSubEle.text().toLong();
		}

		else if(eSubEle.tagName().toLower() == "imageheight")
		{
			pstuResultInfo->lImageHeight = eSubEle.text().toLong();
		}

		else if(eSubEle.tagName().toLower() == "imagename1")
		{
			pstuResultInfo->strSplitImgPath = eSubEle.text();
		}

		else if(eSubEle.tagName().toLower() == "imagename2")
		{
			pstuResultInfo->strAnalyImgPath = eSubEle.text();
		}
	}

	return true;
}

bool ASParaseXml::paraseBubbleInfo( ASResultInfo* pstuResultInfo,const QDomNodeList& subNodeList )
{
	m_lstPtsInfo.clear();
	for (int nSub=0;nSub<subNodeList.count();++nSub)
	{
		QDomNode  subNode = subNodeList.at(nSub);
		QDomElement eSubEle = subNode.toElement();

		ASBubbleInfo  stuBubbleInfo;

 		if(eSubEle.tagName().toLower() == "onebubbleinfo")
 		{
 			if(eSubEle.hasAttribute("Area"))
 				stuBubbleInfo.lBubbleArea = eSubEle.attribute("Area").toLong();
 
 			if(eSubEle.hasAttribute("CenterPT"))
 			{
 				QString strCenterPt = eSubEle.attribute("CenterPT");
 				String2Pt(strCenterPt,stuBubbleInfo.ptCenter);
 			}
 
 			if(eSubEle.hasAttribute("ContounrsPts"))
 			{	
 				QString strPts = eSubEle.attribute("ContounrsPts");

				m_lstPtsInfo << strPts;
 			}
 
 			pstuResultInfo->vtBubbleInfo.push_back(stuBubbleInfo);
 		}
	}
	doParaseXmlThread(m_lstPtsInfo.size(),0);

	return true;
}

bool ASParaseXml::paraseLineInfo( ASResultInfo* pstuResultInfo,const QDomNodeList& subNodeList )
{
	for (int nSub=0;nSub<subNodeList.count();++nSub)
	{
		QDomNode  subNode = subNodeList.at(nSub);
		QDomElement eSubEle = subNode.toElement();


		ASLineInfo  stuLineInfo;

		if(eSubEle.tagName().toLower() == "lineinfo")
		{
			if(eSubEle.hasAttribute("AllBubbleHeight"))
				stuLineInfo.lEachLineHeight = eSubEle.attribute("AllBubbleHeight").toLong();

			if(eSubEle.hasAttribute("AllBubbleLength"))
				stuLineInfo.lTotalPassBleLen = eSubEle.attribute("AllBubbleLength").toLong();

			if(eSubEle.hasAttribute("BubbleNum"))
				stuLineInfo.lTotalPassBleNum = eSubEle.attribute("BubbleNum").toLong();

			if(eSubEle.hasAttribute("BubbleLength"))
			{
				QString strLn = eSubEle.attribute("BubbleLength");
				String2Length(strLn,stuLineInfo.vtlEachPassBleLen);
			}

			pstuResultInfo->vtLineInfo.append(stuLineInfo);
		}
		qDebug()<<qPrintable(eSubEle.tagName()) << qPrintable(eSubEle.attribute("AllBubbleHeight"))
			<<qPrintable(eSubEle.attribute("AllBubbleLength")) <<qPrintable(eSubEle.attribute("BubbleNum"));
	}

	return true;
}

bool ASParaseXml::doParaseXmlThread(int nJobs,int nStarts)
{
	if(nJobs <= 100 && nJobs > 0)
	{
		ASParaseXmlThread* pParaseXmlThread = new ASParaseXmlThread(this);
		pParaseXmlThread->setStartAndEndIndex(nStarts, m_lstPtsInfo.size());
		QThread* pThread = new QThread(this);
		pParaseXmlThread->moveToThread(pThread);
		connect(pThread,SIGNAL(started()),pParaseXmlThread,SLOT(doWork()));
		connect(pParaseXmlThread,SIGNAL(finished()),this,SLOT(finishedThread()));
		m_listThread.append(pParaseXmlThread);
		pThread->start();
		
	}
	else
	{
		int nStratJobs = m_lstPtsInfo.size() / 100;

		for (int n=nStarts;n<nStratJobs;++n)
		{
			ASParaseXmlThread* pParaseXmlThread = new ASParaseXmlThread(this);
			pParaseXmlThread->setStartAndEndIndex(n * 100, (n+1) * 100);
			QThread* pThread = new QThread(this);
			pParaseXmlThread->moveToThread(pThread);
			connect(pThread,SIGNAL(started()),pParaseXmlThread,SLOT(doWork()));
			connect(pParaseXmlThread,SIGNAL(finished()),this,SLOT(finishedThread()));
			m_listThread.append(pParaseXmlThread);
			pThread->start();
		}

		int nThreads = m_lstPtsInfo.size() % 100;
		doParaseXmlThread(nThreads,nStratJobs * 100);
	}

	return true;
}

bool ASParaseXml::delaterParaseXml()
{
	for (int n = 0; n < m_listThread.size();++n)
	{
		ASParaseXmlThread* pParaseXmlThread = m_listThread[n];
		
		if(pParaseXmlThread) delete pParaseXmlThread; pParaseXmlThread = NULL;
	}

	m_listThread.clear();

	return true;
}

void ASParaseXml::finishedThread()
{
	m_nFinishedThread++;
	qDebug()<<"finished count" <<m_nFinishedThread;
	if(m_nFinishedThread == m_listThread.size() )
	{
		
		for (int n = 0; n < m_listThread.size();++n)
		{
			ASParaseXmlThread* pThread = m_listThread[n];
			int nIndex = 0;
			for (int iu=pThread->m_nStartIndex;iu<pThread->m_nEndIndex && nIndex <pThread->m_vtPoints.size();++iu)
			{
				m_stuResultInfo.vtBubbleInfo[iu].vtPoint = pThread->m_vtPoints[nIndex];
				nIndex++;
			}
		}

		delaterParaseXml();
	}

}

void ASParaseXmlThread::setStartAndEndIndex( int nStartIndex,int nEndIndex )
{
	m_nStartIndex = nStartIndex;
	m_nEndIndex = nEndIndex;
}

void ASParaseXmlThread::doParaseXml()
{
	
	for (int n=m_nStartIndex;n<m_nEndIndex;++n)
	{
		VTPoint  vtPoint;
		QString strPts = ((ASParaseXml*)m_pParent)->m_lstPtsInfo[n];
		String2ListPt(strPts,vtPoint);

		m_vtPoints.append(vtPoint);
		
	}
	qDebug()<<QThread::currentThreadId();

	emit finished();
}
